#ifndef _EKOS_PROC_H_
#define _EKOS_PROC_H_

#include "types.h"

typedef uint16_t proc_id_t;

struct sch_info_t
{
	 int pos;
	 proc_id_t prev;
	 proc_id_t next;
};

struct proc_t
{
	 uint32_t flags;
	 union
	 {
		  /* For the in-use processes */
		  struct
		  {
			   /* All operation on the proc structure should acquire
				* the lock */
			   spin_lock_t lock;
			   
			   /* The running cpu, the offset of this field should not
				* be moved since it's depended by kernel.S */
			   uint16_t lcpu;
			   
			   /* The scheduling priority */
			   uint32_t priority;
			   /* The scheduler status */
			   uint32_t sch_status;
			   uint8_t sch_action;
			   uint8_t wait_level;
			   /* Signal processing flags */
			   uint32_t signal_pending;
			   uint32_t signal_processing;
			   uint32_t signal_flags;
			   uintptr_t signal_handler;
			   /* Scheduler signal */
			   uint16_t sch_signal_count;

			   uint32_t eflags;
			   /* The env id of the process */
			   proc_id_t env;
			   /* The temp stack pointer and the kernel stack pointer
				* in Task */
			   uintptr_t esp;
			   uintptr_t ksp;
			   /* For the round robin algorithm */
			   /* All the running and waiting process on the same cpu
				* composite a cycle, and all sleeping procs on same
				* cpu form another */
			   struct sch_info_t sch_info;

			   /* Access point for exception */
			   uint16_t ex_ap;
			   
			   /* For the notify queue */
			   struct
			   {
					uint16_t next;
					uint16_t prev;
			   } notify_queue;
		  };

		  /* For free process structs */
		  struct
		  {
			   proc_id_t free_next;
		  };
	 };
};

#define PFLAG_VALID    0x00000001
#define PFLAG_IDLE     0x00000002
 
#define PSCH_RUN       0
#define PSCH_READY     1
#define PSCH_WAIT      2
#define PSCH_WAIT_R    3
#define PSCH_NOTIFYING 4
#define PSCH_DETACHED  5

#define PACT_WAIT         1
#define PACT_WAIT_PRETEND 2

#define PROC_NULL PROCESS_MAX_COUNT

#define SF_READY     0x01
#define SF_SCH       0x02
#define SF_ACC_GROUP 0x04
#define SF_ACC_ALL   0x08

#define SIG_SCH_TRIGGER(flags) ((flags) >> 16)

#define SIG_SCHEDULE (1 << 0)
#define SIG_USER     (1 << 1)

#define IPC_NULL     0xFFFFFFFFL

#endif
